package com.amkai.aes.webservice.binary.objecthandler.testing;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.amkai.aes.aescommon.itemprovider.ActiveStatus;
import com.amkai.aes.aescommon.service.binary.job.ItemJob;
import com.amkai.aes.aescommon.service.binary.job.RequestJob;
import com.amkai.aes.aescommon.service.binary.job.SearchJob;
import com.amkai.aes.aescommon.service.binary.job.testing.TestJob;
import com.amkai.aes.aescommon.service.result.ItemsResult;
import com.amkai.aes.aescommon.service.search.ItemSearchParameter;
import com.amkai.aes.aescommon.service.search.RegistrationExtendedColumnKind;
import com.amkai.aes.aescommon.service.search.RegistrationSearchParameter;
import com.amkai.aes.aescommon.utilities.RandomStringUtils;
import com.amkai.aes.generatedbeans.dictionary.ItemKind;
import com.amkai.aes.generatedbeans.registration.PatientTransferKind;
import com.amkai.aes.generatedmodels.registration.selector.SelectorDomain;
import com.amkai.aes.generatedmodels.registration.selector.SelectorRequest;
import com.amkai.aes.webservice.binary.JobManager;

public class ParallelSessionTest {
	private static final Log logger = LogFactory.getLog(ParallelSessionTest.class);
	
	private TestJob job;
	private boolean run = true;
	private Date start;
	private int finishCount = 0;
	private String outputs = "";
	
	private RandomStringUtils rs = new RandomStringUtils();
		
	public ParallelSessionTest(TestJob job) {
		this.job = job;
	}
	
	public void start() {
		if (job == null)
			return;
		
		start = new Date();
		
		for (int i = 0; i < job.getThreadCount(); i++) {
			
			Thread searchThread = new Thread(new Runnable() {
				
				public void run() {
					
					if (job.getThreadSleep() > 0) {
						try {
							Thread.currentThread().sleep(job.getThreadSleep());
						} catch (InterruptedException e) {
							logger.error("ParallelSessionTest: ", e);
						}
					}
					
					outputs += "START: " + Thread.currentThread().getId() + "\n";
					
					logger.debug("START: " + Thread.currentThread().getId());
					
					for(int j=0; j<job.getTestCountInThread(); j++) {
						RegistrationSearchParameter psp = new RegistrationSearchParameter("p.lastName", 1, 500);
						ItemSearchParameter itemSearchParameter = new ItemSearchParameter(1, ItemKind.PROCEDURE, new String[] {"name", "shortName"}, ActiveStatus.ACTIVE);
						
						if ((Thread.currentThread().getId() % 2) == 0) {
							psp.setRecent(false);
						} else {
							psp.setRecent(true);
						}
						// KKORNEL: AES-12242
						psp.setExtendedColumnKind(RegistrationExtendedColumnKind.NO_EXTENDED_COLUMN);
						//psp.setExtendedMode(false);
						psp.setRecent(false);
	
						String s = rs.randomAlphabetic(1);
	
						psp.setSearchCondition(s);
						itemSearchParameter.setSearchCondition(s);
						
						outputs += "Thr : "+ Thread.currentThread().getId() +" Search: " + s + " \n";
	
						try {
							Object[][] personResult = (Object[][]) JobManager.processJobObject(new SearchJob(), psp);
							if (personResult.length > 0 && job.getTestKind().equals(TestJob.PARALLEL_SESSION_PERSON_ITEM)) {
								
								Long personId = (Long)personResult[0][0];
								
								SelectorRequest request = new SelectorRequest();
								request.setId(personId);
								request.setPatientTransferKind(PatientTransferKind.GENERAL);
								SelectorDomain domain = (SelectorDomain) JobManager.processJobObject(new RequestJob(), request);
							}
							
							Object[][] itemResult = (Object[][]) JobManager.processJobObject(new SearchJob(), itemSearchParameter);
							if (itemResult.length > 0 && job.getTestKind().equals(TestJob.PARALLEL_SESSION_PERSON_ITEM)) {
								Long itemId = (Long)itemResult[0][0];
								
								ItemJob itemJob = new ItemJob();
								itemJob.setId(itemId);
								itemJob.setItemKind(ItemKind.PROCEDURE);
								ItemsResult itemsResult = (ItemsResult)JobManager.processJobObject(itemJob, null);
							}
							
						} catch (Throwable ex) {
							logger.error("ParallelSessionTest: ", ex);
							outputs += "FAILED in thread: " + Thread.currentThread().getId() + " String: " + s + "\n";
							outputs += ex.getMessage() + "\n";
						}
						
						if (!run) break;
						
						if (job.getShutDownTimeInMins() > 0) {
							Date now = new Date();
							if (now.getTime() - start.getTime() > (job.getShutDownTimeInMins() * 60 * 1000)) {
								run = false;
								break;
							}
						}
					}

					outputs += "Finished: " + Thread.currentThread().getId() + "\n";
					logger.debug("Finished: " + Thread.currentThread().getId() );
					finishCount++;
				}
			});
			searchThread.start();
		}
		
		while(finishCount != job.getThreadCount()) {
			//waiting for the threads
		}
		
		logger.debug("---------------------------------------------------------------");
		logger.debug("----- Test results --------------------------------------------\n");
		logger.debug(outputs);
		logger.debug("---------------------------------------------------------------");
	}
}
